#include "ai_search.h"



void search_algorithm::get_commands()
{
	commands.clear();
	std::cout << "AI BEGIN" << std::endl;

	//adding root node
	search_tree = new ai_states_node( 0, new ai_game_state( game::get_instance()->get_current_state()->clone() ) );
	//creating help computes
	search_tree->state->state->reachable_places = help_computes::map_places_reachable( search_tree->state->state );
	search_tree->state->state->estimated_places = help_computes::map_places_estimate( search_tree->state->state );
	search_tree->state->state->dangerous_places = help_computes::map_places_dangerous( search_tree->state->state );
	search_tree->state->state->dangerous_places_nobody = help_computes::map_places_dangerous_nobody( search_tree->state->state );
	search_tree->state->state->attackable_places = help_computes::map_places_attackable( search_tree->state->state );
	search_tree->state->state->score = help_computes::game_state_estimate( search_tree->state->state );
	best_state = search_tree;
	std::cout << "Aktual depth: " << search_tree->depth << std::endl;
	search_state( search_tree );

	for ( ai_states_node* i = best_state; i->parent != 0; i = i->parent )
	{
		commands.push_front( i->state->command );
	}

	delete search_tree;
	std::cout << "AI END" << std::endl;
};



void search_algorithm::search_state( ai_states_node* state_node )
{
	if ( state_node->state->command == "NXT" )
	{
		++state_node->depth;
		if ( state_node->depth > parameters::get_instance()->ai_parameters[ "SEARCH" ][ "depth" ] )
		{
			state_node->state->state->reachable_places = help_computes::map_places_reachable( state_node->state->state );
			state_node->state->state->estimated_places = help_computes::map_places_estimate( state_node->state->state );
			state_node->state->state->dangerous_places = help_computes::map_places_dangerous( state_node->state->state );
			state_node->state->state->dangerous_places_nobody = help_computes::map_places_dangerous_nobody( state_node->state->state );
			state_node->state->state->attackable_places = help_computes::map_places_attackable( state_node->state->state );
			state_node->state->state->score = help_computes::game_state_estimate( state_node->state->state );
			if ( state_node->state->state->score > best_state->state->state->score )
				best_state = state_node;
			return;
		}
		else
		{
			std::cout << "Aktual depth: " << state_node->depth << std::endl;
		}
	}

	ai_game_state* generated_state;
	ai_states_node* generated_node;

	// new children

	//adding end of the turn as the last possibility to do
	generated_state = new ai_game_state( state_node->state, "NXT" );
	generated_node = new ai_states_node( state_node, generated_state );

	//recursive call to all new children
	for ( std::list< ai_states_node* >::iterator it = state_node->children.begin(); it != state_node->children.end(); ++it )
		search_state( *it );
};



ai_states_node::~ai_states_node()
{
	if ( !children.empty() )
		for ( std::list< ai_states_node* >::iterator it = children.begin(); it != children.end(); ++it )
		{
			delete *it;
		}
	delete state;
};